#include "stinger.h"
#include "build_type.h"
#include "stinger_vertex.h"
#include "stinger_edge.h"

pmem::obj::persistent_ptr<stinger> stinger_root;
pmem::obj::pool<stinger> pop;

void init_stinger() {

    if (file_exists(PERSIST_FILE_PATH) != 0) {
        pop = pmem::obj::pool<stinger>::create(PERSIST_FILE_PATH, LAYOUT, POOLSIZE);
    } else {
        pop = pmem::obj::pool<stinger>::open(PERSIST_FILE_PATH, LAYOUT);
    }
    stinger_root = pop.root();
    if (stinger_root->mapper == nullptr) {
        pmem::obj::transaction::run(pop, [&] {
            stinger_root->mapper = pmem::obj::make_persistent<hashmap>();
        });
        stinger_root->mapper->runtime_initialize();
    } else {
        stinger_root->mapper->runtime_initialize();
        stinger_root->mapper->defragment();
    }
}

void close_stinger(pmem::obj::pool_base &pop) {
    stinger_root->mapper->defragment();
    pop.close();
}





int main() {
	
    
    
    init_stinger();

    //添加顶点映射
    add_vertex_type_mapping("user");
    int res1 = add_vertex_type_mapping("user");
    assert(res1 == -1);
    add_vertex_type_mapping("good");
    add_vertex_type_mapping("order");

    //添加边的映射
    add_edge_type_mapping("like");
    int res2 = add_edge_type_mapping("like");
    assert(res2 == -1);
    add_edge_type_mapping("buy");
    add_edge_type_mapping("contain");
    add_edge_type_mapping("following");


    //插入一个顶点
    insert_vertex("Jack", "user");
    insert_vertex("Jerry", "user");


    //插入边
    //10个Jerry正在关注Jack
    for (int i = 0; i < 10; i++) {
        insert_edge("Jerry" + std::to_string(i), "user", "Jack", "user", i + 1, i + 1, "following", 1);
    }
    for (int i = 0; i < 10; i++) {
        insert_edge("Jerry", "user", "Beer" + std::to_string(i), "good", i + 1, i + 1, "like", 1);
    }

    //Jack收藏了10件商品
    for (int i = 0; i < 10; i++) {
        insert_edge("Jack", "user", "Bread" + std::to_string(i), "good", i + 1, i + 1, "like", 1);
    }

    for (int i = 0; i < 20; i++) {
        insert_edge("Rose" + std::to_string(i), "user", "Book" + std::to_string(i), "good", i + 1, i + 1, "like", 1);
    }

    //获取顶点
    for (int i = 0; i < 10; i++) {
        struct stinger_vertex *vertex1 = get_vertex("Bread" + std::to_string(i), "good");
        assert(vertex1 != nullptr);
        struct stinger_vertex *vertex2 = get_vertex("Beer" + std::to_string(i), "good");
        assert(vertex2 != nullptr);
        struct stinger_vertex *vertex3 = get_vertex("Jerry" + std::to_string(i), "user");
        assert(vertex3 != nullptr);
    }

    //获取边
    for (int i = 0; i < 20; i++) {
        struct stinger_edge *edge = get_edge_by_name("Rose" + std::to_string(i), "user", "Book" + std::to_string(i), "good", "like");
        assert(edge != nullptr);
        std::cout << edge->timeFirst << "--" << edge->timeRecent << std::endl;
    }

    struct stinger_edge *edge2 = get_edge_by_name("Bread1", "good", "Book1", "good", "like");
    assert(edge2 == nullptr);

    struct stinger_vertex *vertex = get_vertex("Jack", "user");
    assert(vertex->inDegree == 10);
    assert(vertex->outDegree == 10);

    // for (int i = 0; i < 10; i++) {
    //     struct stinger_vertex *vertex1 = get_vertex("Jerry" + std::to_string(i), "user");
    //     assert(vertex1 != nullptr);
    //     std::cout << "出度 = " << vertex1->outDegree << ", 入度 = " << vertex1->inDegree << std::endl;
    // }

    //删除一个顶点
    delete_vertex_by_name("Jack", "user");


    //获取一个顶点
    struct stinger_vertex *vertex1 = get_vertex("Jack", "user");
    assert(vertex1 == nullptr);


    // for (int i = 0; i < 10; i++) {
    //     struct stinger_vertex *vertex1 = get_vertex("Jerry" + std::to_string(i), "user");
    //     assert(vertex1 != nullptr);
    //     std::cout << vertex1->outDegree << std::endl;
    // }


    std::cout << "所有操作执行成功" << std::endl;


	close_stinger(pop);
	return 0;
}